/*
    This file is part of Epoch <http://code.google.com/p/epoch/>.
    
    Copyright (C) 2011  Adam Meily <meily.adam@gmail.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/


#include "NodeConfig.h"
#include <QtCore/QStringList>

NodeConfig::NodeConfig(const QList< QSsl::SslProtocol >& supportedSsl,
                       bool requiresSsl, int version)
        : m_supportedSsl(supportedSsl),
          m_requiresSsl(requiresSsl),
          m_version(version)
{

}

NodeConfig::NodeConfig(const NodeConfig& other)
        : m_supportedSsl(other.m_supportedSsl), m_version(other.m_version),
          m_requiresSsl(other.m_requiresSsl)        
{
    
}

NodeConfig* NodeConfig::fromRecord(const Record& record)
{
    NodeConfig *config = NULL;
    QString versionStr = record.value("version");
    QString requiresStr = record.value("requires-ssl").toLower();
    QString supportedStr = record.value("supported-ssl").toLower();
    
    if(versionStr.isEmpty() || requiresStr.isEmpty())
        return config;
    
    bool check;
    int version = versionStr.toInt(&check, 10);
    if(!check)
        return config;
    
    bool requires = (requiresStr == "yes" || requiresStr == "true" ||
                     requiresStr == "1");
    
    QStringList protos = supportedStr.split(',', QString::SkipEmptyParts);
    QList<QSsl::SslProtocol> supported;
    
    int len = protos.length();
    for(int i = 0; i < len; i++)
    {
        QString test(protos[i].trimmed());
        if(test == "tlsv1")
            supported.append(QSsl::TlsV1);
        else if(test == "sslv3")
            supported.append(QSsl::SslV3);
        else if(test == "sslv2")
            supported.append(QSsl::SslV2);
    }
    
    config = new NodeConfig(supported, requires, version);
    return config;
}


NodeConfig::~NodeConfig()
{

}

NodeConfig& NodeConfig::operator=(const NodeConfig& other)
{
    m_requiresSsl = other.m_requiresSsl;
    m_supportedSsl = other.m_supportedSsl;
    m_version = m_version;
}


int NodeConfig::version() const
{
    return m_version;
}

bool NodeConfig::requiresSsl() const
{
    return m_requiresSsl;
}

const QList< QSsl::SslProtocol >& NodeConfig::supportedSsl() const
{
    return m_supportedSsl;
}

QSsl::SslProtocol NodeConfig::getSsl(const NodeConfig& other) const
{
    QList<QSsl::SslProtocol> all;
    all.append(QSsl::TlsV1);
    all.append(QSsl::SslV3);
    all.append(QSsl::SslV2);
    QSsl::SslProtocol ret = QSsl::UnknownProtocol;
    
    for(int i = 0; i < 3 && ret == QSsl::UnknownProtocol; i++)
    {
        if(m_supportedSsl.indexOf(all[i]) >= 0 &&
                other.m_supportedSsl.indexOf(all[i]) >= 0)
            ret = all[i];
    }
    
    return ret;
}

Record NodeConfig::toRecord() const
{
    Record r;
    r["version"] = QString::number(m_version, 10);
    r["requires-ssl"] = m_requiresSsl ? "true" : "false";
    
    QStringList supported;
    int len = m_supportedSsl.length();
    for(int i = 0; i < len; i++)
    {
        if(m_supportedSsl[i] == QSsl::TlsV1)
            supported.append("tlsv1");
        else if(m_supportedSsl[i] == QSsl::SslV3)
            supported.append("sslv3");
        else if(m_supportedSsl[i] == QSsl::SslV2)
            supported.append("sslv2");
    }
    
    r["supported-ssl"] = supported.join(",");
    return r;
}
